/*==============================================================================
Header Files and Global Defines
==============================================================================*/
#include "resource.h"       //Header File for Resource IDs and Headers
//Replace this header file as needed by your project.

/*==============================================================================
Global Variables
==============================================================================*/
//~~~~~Fire Particles
    unsigned int fire_objects=100;
    typedef struct
    {
        float size;
        float x_pos;
        float x_store;
        float y_pos;
        float z_pos;
        float speed_move;
        float red;
        float green;
        float blue;
        float alpha;
        bool start_assign;
    }
    fire_struct;
    fire_struct *fire;

/*==============================================================================
FUNCTION PROTOTYPES
==============================================================================*/
//Particle Generator Inilization
bool xia_IniFire(int quantity, float size, float speed_edit);
//Particle Generator De-inilization
void xia_CleanFire();
//Particle Generator Function
void xia_GenFire(float limit_x1, float limit_x2, float max_y, float min_y, float z, float speed_fade, 
                 float speed_point, float r, float g, float b, float a, float speed_mod);
//Particle Drawing Function
inline void xia_PersonalDrawParticle(float size_x, float size_y);
/*==============================================================================
Fire Particle Generator Code
==============================================================================*/
//Fire Inilization Code
bool xia_IniFire(int quantity, float size, float speed_edit)
{
    fire_objects=quantity;
    fire=new fire_struct[fire_objects];
    if(fire == NULL)
    {
        MessageBox(GetActiveWindow(),"Memory Allocation", "Error",MB_ICONERROR);
        return FALSE;
    }
    for(int loop=0; loop < fire_objects; loop++)
    {
        fire[loop].size=rand()%100*size;
        fire[loop].x_pos=0.0;
        fire[loop].y_pos=0.0;
        fire[loop].z_pos=-2;
        fire[loop].speed_move=rand()%100*speed_edit;
        do
        {
           fire[loop].speed_move=rand()%100*speed_edit;
        }while(fire[loop].speed_move < 9*speed_edit);
        fire[loop].red=rand()%100*.01;
        fire[loop].green=rand()%100*.01;
        fire[loop].blue=rand()%100*.01;
        fire[loop].alpha=1.0;
        fire[loop].start_assign=FALSE;
    }
}

//Fire Memory De-allocation Code
void xia_CleanFire()
{
    delete [] fire;
    fire=NULL;
}

//Fire Particle Generation Code
void xia_GenFire(float limit_x1, float limit_x2, float max_y, float min_y, float z, float speed_fade, 
                 float speed_point, float r, float g, float b, float a, float speed_mod)
{
    static float distance, xTarget;
    for(int p=0; p < fire_objects; p++)
    {
        glPushMatrix();
    //Assign all particles to the bottom since that is where a fire typically starts at and randomize
        if(!fire[p].start_assign)
        {
            fire[p].y_pos=min_y;
            fire[p].start_assign=TRUE;
        //Find the distance between two specified points -> (x1,y1) and (x2,y2)
            if(limit_x1 <= 0 && limit_x2 <= 0)
            {
               distance=limit_x1-limit_x2; //If both are negative
            }
            else if(limit_x1 >= 0 && limit_x2 >= 0) //If both are positive
            {
               if(limit_x1 < limit_x2) //If first x is greater than the second x
               {
                   distance=limit_x2-limit_x1;
               }
               else //If first x is smaller than the second x
               {
                   distance=limit_x1-limit_x2;
               }
            }
            else //If one is positive and one is negative
            {
               float temp_x1, temp_x2;
               //Make sure both are positive before adding
               if(limit_x1 < 0) //Is limit_x1 smaller than 0?
               {
                  temp_x1=-limit_x1;
               }
               else
               {
                  temp_x1=limit_x1;
               }
               if(limit_x2 < 0) //Is limit_x2 smalelr than 0?
               {
                  temp_x2=-limit_x2;
               }
               else
               {
                  temp_x2=limit_x2;
               }
               distance=temp_x1+temp_x2;
            }
        //If distance is negative then change it
            if(distance < 0)
            {
               distance=-distance;
            }
        //Randomize particle location in an area between x1 and x2 to achieve that spread out effect
            float range;
            range=rand()%100*distance*.01;
            if(limit_x1 < limit_x2) //If the first x is smaller
            {
               fire[p].x_pos=range+limit_x1;
            }
            else //If the second is smaller
            {
               fire[p].x_pos=range+limit_x2;
            }
        //Store original value of x so the flame will be uniform at the base again.
            fire[p].x_store=fire[p].x_pos;
        }
    //Color
        if(r <= 1 && g <= 1 && b <= 1)
        {
            glColor4f(r,g,b,fire[p].alpha);
        }
        else
        {
            glColor4f(fire[p].red, fire[p].green,fire[p].blue,fire[p].alpha);
        }
    //If a particle goes over its y max value or fades out then send it to the bottom
        if((fire[p].y_pos > max_y-fire[p].size/2) || (fire[p].alpha < 0.0))
        {
            fire[p].y_pos=min_y;
            fire[p].alpha=1.0;
            fire[p].x_pos=fire[p].x_store;
        }
    //Begin Positioning and Drawing
        glTranslatef(fire[p].x_pos,fire[p].y_pos,fire[p].z_pos);
        xia_PersonalDrawParticle(fire[p].size,fire[p].size);
    //Increment Particle Position and Fade
        fire[p].y_pos+=fire[p].speed_move*speed_mod;
        fire[p].alpha-=fire[p].speed_move*speed_fade;
    //Attraction towards a point
        if(limit_x1 < limit_x2)
        {
            xTarget=distance/2+limit_x1;
        }
        else
        {
            xTarget=distance/2+limit_x2;
        }
        if(xTarget < fire[p].x_pos)
        {
            fire[p].x_pos-=fire[p].speed_move*speed_point;
        }
        else if(xTarget > fire[p].x_pos)
        {
            fire[p].x_pos+=fire[p].speed_move*speed_point;
        }
        glPopMatrix();
    }
}

//Particle Drawing
inline void xia_PersonalDrawParticle(float size_x, float size_y)
{
    glBegin(GL_TRIANGLE_FAN);
        glTexCoord2f(0.0,0.0); glVertex3f(0.0,0.0,0.0);
        glTexCoord2f(1.0,0.0); glVertex3f(size_x,0.0,0.0);
        glTexCoord2f(1.0,1.0); glVertex3f(size_x,size_y,0.0);
        glTexCoord2f(0.0,1.0); glVertex3f(0.0,size_y,0.0);
    glEnd();
}
